<?php
define('DEBUG', true);
require_once __DIR__.'/../src/aspyct/Aspyct.php';

class DocEnvironment extends Environment {
    public function getRoutes() {
        return array(
            '/' => 'home',
            '/{class:[A-Z][\w\d]*}' => 'class.details',
            '/{class:[A-Z][\w\d]*}::{method:\w[\w\d]*}' => 'class.method',
            '/{class:[A-Z][\w\d]*}::${property:\w[\w\d]*}' => 'class.property'
        );
    }
    
    public function getRouteMapping() {
        return array(
            'home' => 'classList',
            'class.details' => 'classDetails'
        );
    }
    
    public function getConfig() {
        return array_merge(parent::getConfig(), array(
            'template.source' => __DIR__ . '/templates'
        ));
    }
    
    public function getClassListController() {
        $controller = new ClassListController();
        $this->initDocController($controller);
        
        return $controller;
    }
    
    public function getClassDetailsController() {
        $controller = new ClassDetailsController();
        $this->initDocController($controller);
        
        return $controller;
    }
    
    protected function initDocController(DocController $controller) {
        $this->initController($controller);
    }
}

class DocController extends Controller {
    
}

class ClassListController extends DocController {
    public function do_GET(Request $request) {
        return $this->render('class-list', array(
            'classes' => Aspyct::listClasses()
        ));
    }
}

class ClassDetailsController extends DocController {
    public function do_GET(Request $request) {
        $class = Aspyct::getClass($request->getArgument('class'));
        return $this->render('class-details', array(
            'class' => $class,
            'publicMethods' => $class->getDeclaredMethods(
                    ReflectionDocumentedMethod::IS_PUBLIC),
            'protectedMethods' => $class->getDeclaredMethods(
                    ReflectionDocumentedMethod::IS_PROTECTED),
            'properties' => $class->getProperties()
        ));
    }
}

class MethodDetailsController extends DocController {
    
}

function putType($type) {
    echo formatType($type);
}

function formatType($type) {
    // May be an array
    if (substr($type, -2) === '[]') {
        $class = substr($type, 0, -2);
        $suffix = '[]';
    }
    else {
        $class = $type;
        $suffix = '';
    }
    
    if (Aspyct::classExists($class)) {
        $url = Environment::getInstance()->urlWriter->
                urlTo('class.details', array('class' => $class));
        
        return '<a class="type" href="' . $url . '">' . escape($class) . '</a>' . $suffix;
    }
    elseif (class_exists($class)) {
        // Is this a built-in class ?
        $rc = new ReflectionClass($class);
        
        if ($rc->isInternal()) {
            $url ='http://php.net/manual-lookup.php?pattern='.urlencode($class);
            return '<a class="type internal" href="'.$url.'">'.escape($class).
                    '</a>'.$suffix;
        }
    }
    else {
        return '<span class="type">' . escape($type) . '</span>';
    }
}

$app = new Application(new DocEnvironment());
$app->run();
